package day_05_03_FourFunctionalInterface;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @Description 异步回调
 * @Author shihan
 * @Date 2020/11/8 17:19
 * @Version 1.0
 */
public class CompletableFutureDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "\t没有返回值，update mysql OK ！");
        });
        System.out.println(completableFuture.get());

        //===============================================================================================
        //有返回值的异步执行
        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "\t有返回值！");
            //int i = 10/0;
            try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
            return 1024;
        });

        /**
         * 异步回调：
         *  1、当异步线程执行完毕后，回调 whenComplete、exceptionally 方法；
         *  2、获取结果这里，依然是能往后放就往后放，提升性能（因为这两个方法会造成阻塞，直到异步线程执行完毕回调触发后，才接触阻塞）
         *  3、如果异步线程，内部执行出现异常，依然会调用 whenComplete 和 exceptionally 这两个方法（因为执行完成了，同时还发生了异常）
         */
        //whenComplete 当正常执行完成后，结果和异常封装到两个参数中
        Integer result = integerCompletableFuture.whenComplete((res, e) -> {      //BiConsumer<T,U>
            System.out.println("res:" + res);   //正常执行完的结果
            System.out.println("e:" + e);       //遇到的异常信息
        }).exceptionally(e -> {                 //为正常执行完成，出现异常时调用的方法，且异常信息封装到 e 参数中     Function<T,R>
            System.out.println("e:" + e.getMessage());
            return 444;
        }).get();

        System.out.println(result);
    }

}
